home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 …SCII & the Runetime Code / ADC Developer CD (1992-07) (''Butch ASCII And The Runtime Code'')_iso / Dev.CD 199207.iso / Tools & Apps / Devices & Hardware / A⁄ROSE / MultiThread / TestMultiThread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-21  |  5.5 KB  |  206 lines  |  [TEXT/MPS ]

  1. /*
  2.     Program to test multi thread A/ROSE task
  3.     
  4.     Written by:    Anumele D. Raja
  5.     
  6.     Date:        March 19, 1991
  7.     
  8.     Copyright @ Apple Computer, Inc.  1991
  9.     
  10.     This program opens kNumOfQueues queues and sends messages to another task
  11.         Receives message in a completion routine sets up a flag in global area
  12.         There is a flag for the original message and the reply.
  13.         When all the replies have been received the program closes all the queues and quits.
  14.         You can quit be pressing Command-.
  15.     
  16. */
  17.  
  18. #include <StdIO.h>
  19. #include <CursorCtl.h>
  20. #include <StdLib.h>
  21.  
  22. #include "MultiThread.h"
  23.  
  24. #define    kNumOfQueues 16                // Number of queues including the main queueue
  25. enum { kFalse, kTrue };
  26.  
  27. short origFlag[kNumOfQueues], replyFlag[kNumOfQueues];
  28. tid_type origFrom[kNumOfQueues], origTo[kNumOfQueues];
  29. tid_type replyFrom[kNumOfQueues], replyTo[kNumOfQueues];
  30. struct QueueEntry *qPtr[kNumOfQueues];
  31. tid_type    myTID[kNumOfQueues];
  32.  
  33. void CleanUp(void)
  34. {
  35.     int i;
  36.     
  37.     for (i = 0; i < kNumOfQueues; i++) {
  38.         if (qPtr[i]) {
  39.             if (myTID[i]) {
  40.                 qPtr[i]->KillReceive();            // kill all outstanding receives
  41.                 qPtr[i]->CloseQueue();            // close queue if it is opened
  42.             }
  43.             DestroyQueue(qPtr[i]);                // destory queue
  44.         }
  45.     }
  46. }
  47.  
  48. void MsgRecd(struct mMessage *msgPtr)
  49. {
  50.     short code;
  51.     tid_type temp;
  52.     short task;
  53.     
  54.     code = msgPtr->mCode;
  55.     task = code >> 1;
  56.  
  57.     if (code & 1) {                        // if it is reply
  58.         replyFlag[task] = kTrue;        // set flag for reply
  59.         replyFrom[task] = msgPtr->mFrom;
  60.         replyTo[task] = msgPtr->mTo;
  61.         qPtr[task]->FreeMsg(msgPtr);    // queue is the queue of the original sender
  62.     }
  63.     else {
  64.         if (msgPtr->mStatus < 0) {                    // is it an undelived message
  65.             
  66.             // If so set reply to true and delete the message
  67.             
  68.             replyFlag[task] = kTrue;                    // set flag for reply
  69.             replyFrom[task] = msgPtr->mFrom;
  70.             replyTo[task] = msgPtr->mTo;
  71.             qPtr[task & 0x7F]->FreeMsg(msgPtr);        // extract the queue number of the original sender
  72.         }
  73.         else {
  74.             origFlag[task] = kTrue;                    // set flag for original message
  75.             origFrom[task] = msgPtr->mFrom;
  76.             origTo[task] = msgPtr->mTo;
  77.             temp = msgPtr->mFrom;
  78.             msgPtr->mFrom = msgPtr->mTo;
  79.             msgPtr->mTo = temp;
  80.             msgPtr->mCode |= 1;                        // reply code
  81.             qPtr[msgPtr->mSData[0]]->Send(msgPtr);
  82.         }
  83.     }
  84.     
  85.     // Issue another receive
  86.     
  87.     qPtr[(code & 0xFF)>>1]->Receive(OS_MATCH_ALL, OS_MATCH_ALL, OS_MATCH_ALL, 0, MsgRecd);
  88. }
  89.  
  90. main()
  91. {
  92.     struct mMessage *msgPtr[kNumOfQueues];
  93.     short i, allDone;
  94.     
  95.     atexit(CleanUp);            // Install clean up routine
  96.     
  97.     //  Make new queues
  98.     
  99.     for (i = 0; i < kNumOfQueues; i++) {
  100.         
  101.         // Create queues
  102.         
  103.         if ((qPtr[i] = CreateQueue()) == 0) {
  104.             printf("*** Could not make a queue %d ***\n", i);
  105.         }
  106.         else {
  107. //            printf("Made a queue %d with pointer %08X\n", i, qPtr[i]);
  108.         }
  109.     }
  110.     
  111.     //  Open all queues
  112.  
  113.     for (i = 0; i < kNumOfQueues; i++) {
  114.         if (qPtr[i]) {                                        // If it is a valid queue
  115.             if ((myTID[i] = qPtr[i]->OpenQueue(0)) == 0) {
  116.                 printf("*** Could not open queue %d ***\n", i);
  117.             }
  118.             else {
  119.                 printf("Opened queue for %d with Task ID %d\n", i, myTID[i]);
  120.             }
  121.         }
  122.     }
  123.     
  124.     //  Get a message for each queue
  125.     
  126.     for (i = 0; i < kNumOfQueues; i++) {
  127.         if (qPtr[i]) {                                    // If it is a valid queue
  128.             if (msgPtr[i] = qPtr[i]->GetMsg()) {        // Get a message
  129. /*                printf("Message buffer for %d with TID of %d mFrom of %d at %08X\n",
  130.                             i, qPtr[i]->GetTID(), msgPtr[i]->mFrom, msgPtr);
  131. */
  132.             }
  133.             else {
  134.                 printf("Could not get a message for queue with Task ID of %d\n", qPtr[i]->GetTID());
  135.             }
  136.         }
  137.     }
  138.     
  139.     //  Now send messages and receive with completion for different threads
  140.     
  141.     for (i = 0; i < kNumOfQueues; i++) {
  142.         if (msgPtr[i] && myTID[i]) {            // if there is a message buffer and it is a valid task
  143.             int dest;
  144.             
  145.             dest = kNumOfQueues-1-i;    //  Compute destination queue number (reverse order)
  146.             
  147.             // The following line checks if there is a valid queue entry
  148.             
  149.             dest = qPtr[dest] ? dest : i;    // find the actual destination
  150.                         // Get TID of a different queue if it is there.  Otherwise get TID of self
  151.             msgPtr[i]->mTo = qPtr[dest]->GetTID() ? qPtr[dest]->GetTID() : 100;
  152.             msgPtr[i]->mCode = i*2;        // message code is queue number * 2 (original sender)
  153.             msgPtr[i]->mSData[0] = dest;    // destination queue number in mSData[0]  (receiver)
  154.             replyFlag[i] = kFalse;            // reset reply flag for sender
  155.             origFlag[dest] = kFalse;        // reset flag so that the receiver can set it
  156.     
  157.             printf("Sending a message from %d to %d\n", msgPtr[i]->mFrom, msgPtr[i]->mTo);
  158.             qPtr[i]->Send(msgPtr[i]);
  159.             
  160.             // Issue a receive with completion
  161.             
  162.             if (msgPtr[i] = qPtr[i]->Receive(OS_MATCH_ALL, OS_MATCH_ALL, OS_MATCH_ALL, 0, MsgRecd)) {
  163.                 printf("Receive call returned an error for %d\n", i);
  164.             }
  165.         }
  166.     }
  167.     
  168.     allDone = kFalse;
  169.     
  170.     //  Loop till all messages and replies have been received by checking the origFlag and replyFlag
  171.     
  172.     while (!allDone) {
  173.         SpinCursor(1);                // give a chance for the user to abort
  174.         allDone = kTrue;            // first assume all done
  175.         for (i = 0; i < kNumOfQueues; i++) {
  176.             if (qPtr[i]) {
  177.                 if (origFlag[i]) {
  178.                     if (origFlag[i] > 0) {
  179.                         printf("Original message received from %d to %d\n", origFrom[i], origTo[i]);
  180.                         origFlag[i] |= 0x8000;        // This is to make sure we print out only once
  181.                     }
  182.                 }
  183.                 else {
  184.                     allDone = kFalse;
  185.                 }
  186.                     
  187.                 // Now check the reply flags
  188.                 
  189.                 if (replyFlag[i]) {
  190.                     if (replyFlag[i] > 0) {
  191.                         printf("Reply message received from %d to %d\n", replyFrom[i], replyTo[i]);
  192.                         replyFlag[i] |= 0x8000;        // This is to make sure we print out only once
  193.                     }
  194.                 }
  195.                 else {
  196.                     allDone = kFalse;
  197.                 }
  198.             }
  199.         }
  200.     }
  201.  
  202.     // All done clean up
  203.  
  204.     printf("Good Bye!\n");
  205. }
  206.